﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NHibernate;
using NHibernate.Cfg;
using System.Web;
namespace Com.Core.Common
{
    public static class DBHelper
    {
        private static readonly string sessionKey = "NHibernateSessionKey";
        private static ISessionFactory _ISessionFactory = null;
        /// <summary>
        /// 是否把ISession放入HttpSession中
        /// 经过查询多数资料表明 ISession不应该当放入HttpSession中
        /// 通常一个ISession对象应该是一个生存期比较短的对象 在HttpApplication中会产生无数的
        /// ISession对象 而ISession又相对独立 所以数据库Update之后 别的ISession不能对对象做相应的更新
        /// </summary>
        public static bool LoadISessionFromHttpSession = false;
        /// <summary>
        /// 建立SessionFactory
        /// </summary>
        public static ISessionFactory BuildSessionFactroy
        {
            get
            {
                if (_ISessionFactory == null)
                {
                    Configuration cfg = new Configuration();
                    cfg.Configure();

                    _ISessionFactory = cfg.BuildSessionFactory();
                }
                return _ISessionFactory;
            }
        }
        /// <summary>
        /// 关闭Session。
        /// </summary>
        /// <remarks>
        /// 应该在EndRequest事件发生时被调用，写在HttpModule中。
        /// </remarks>
        public static void CloseSession()
        {
            if (HttpContext.Current != null)
            {
                if (LoadISessionFromHttpSession)
                {
                    if (HttpContext.Current.Session != null)
                    {
                        ISession session = HttpContext.Current.Session[sessionKey] as ISession;
                        if (session != null)
                        {

                            session.Close();
                            HttpContext.Current.Session.Remove(sessionKey);
                        }
                    }
                }
                else
                {
                    if (HttpContext.Current.Items.Contains(sessionKey))
                    {
                        ISession session = (ISession)HttpContext.Current.Items[sessionKey];
                        session.Close();
                        HttpContext.Current.Items.Remove(sessionKey);
                    }
                }
            }
            if (_ISession != null)
            {
                _ISession.Close();
                _ISession = null;
            }
        }
        private static ISession _ISession = null;

        /// <summary>
        /// 获取一个ISession
        /// </summary>
        public static ISession GetISession
        {
            get
            {
                if (HttpContext.Current != null)
                {
                    if (LoadISessionFromHttpSession)
                    {
                        if (HttpContext.Current.Session != null)
                        {
                            ISession session;
                            session = HttpContext.Current.Session[sessionKey] as ISession;
                            if (session == null)
                            {
                                session = BuildSessionFactroy.OpenSession();
                                HttpContext.Current.Session[sessionKey] = session;
                            }
                            return session;
                        }
                    }
                    else
                    {
                        ISession session;
                        if (HttpContext.Current.Items.Contains(sessionKey))
                        {
                            session = (ISession)HttpContext.Current.Items[sessionKey];
                        }
                        else
                        {
                            session = BuildSessionFactroy.OpenSession();
                            HttpContext.Current.Items[sessionKey] = session;
                        }
                        return session;
                    }
                }
                if (_ISession == null)
                {
                    _ISession = BuildSessionFactroy.OpenSession();
                }
                return _ISession;
            }
        }

        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待插入的实例。</param>
        public static void TransInsert(object item)
        {
            if (LoadISessionFromHttpSession)
                CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();
            try
            {
                _ISession.Save(item);
                transaction.Commit();

                LogicUtil.AddALog("Add New " + item.GetType().Name + " :" + item.ToString());
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new Exception("Save " + item.GetType().ToString() + " Exception! Object:" + item.ToString(), ex);
            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }

        /// <summary>
        /// 将指定的实例更新到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待更新的实例。</param>
        public static void TransUpdate(object item)
        {

            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {
                _ISession.Update(item);
                transaction.Commit();
                LogicUtil.AddALog("Update " + item.GetType().Name + " :" + item.ToString());
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new Exception("Update " + item.GetType().ToString() + " Exception! Object:" + item.ToString(), ex);
            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }
        /// <summary>
        /// 将指定的实例更新到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待更新的实例。</param>
        public static void TransSaveOrUpdate(object item)
        {
            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {
                _ISession.SaveOrUpdate(item);
                transaction.Commit();
                LogicUtil.AddALog("SaveOrUpdate " + item.GetType().Name + " :" + item.ToString());
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new Exception("Update " + item.GetType().ToString() + " Exception! Object:" + item.ToString(), ex);
            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }
        /// <summary>
        /// 在数据库中删除指定的实例。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待删除的实例。</param>
        public static void TransDelete(object item)
        {
            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {

                _ISession.Delete(item);
                transaction.Commit();
                LogicUtil.AddALog("Delete " + item.GetType().Name + " :" + item.ToString());
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new Exception("Delete " + item.GetType().ToString() + " Exception! Object:" + item.ToString(), ex);
            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }



        /// <summary>
        /// 根据编号删除某个类
        /// </summary>
        /// <param name="objName">类名，注意大小写</param>
        /// <param name="id">编号，注意，这个类中一定要有id这个字段</param>
        internal static void TransDeleteByID(string objName, int id)
        {
            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {
                _ISession.CreateQuery("delete  from " + objName + "  where id=" + id + "").ExecuteUpdate();
                transaction.Commit();

            }
            catch (Exception ex)
            {
                transaction.Rollback();

            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }
        /// <summary>
        /// 执行删除语句
        /// </summary>
        /// <param name="hql"></param>
        internal static void TransDeleteByHQL(string hql)
        {
            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {
                _ISession.CreateQuery(hql).ExecuteUpdate();

                transaction.Commit();

            }
            catch (Exception ex)
            {
                transaction.Rollback();

            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }


        internal static IQuery ExecuteHQL(string HQL)
        {
            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {
                IQuery iq = _ISession.CreateQuery(HQL);
                transaction.Commit();
                return iq;


            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return null;
            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }

        public static void DeleteByHQL(string hql)
        {
            CloseSession();
            ISession _ISession = GetISession;
            ITransaction transaction = _ISession.BeginTransaction();

            try
            {
                _ISession.CreateQuery(hql).ExecuteUpdate();
                transaction.Commit();



            }
            catch (Exception ex)
            {
                transaction.Rollback();

            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }

        internal static Object GetObject(Type type, int id)
        {
            CloseSession();
            ISession _ISession = GetISession;
            try
            {
                return _ISession.Load(type, id);



            }
            catch (Exception ex)
            {
                return null;

            }
            finally
            {
                if (LoadISessionFromHttpSession)
                    CloseSession();
            }
        }

    }
}
